#[cfg(test)]
mod sort {
    use std::collections::HashMap;
    // 所有的集合类型都是动态的，意味着它们没有固定的内存大小，因此它们底层的数据都存储在内存堆上
    // 然后通过一个存储在栈中的引用类型来访问

    // HashMap 并没有包含在 Rust 的 prelude

    // HashMap 使用的哈希函数是 SipHash，它的性能不是很高，但是安全性很高
    // key 实现了 std::cmp::Eq -->可比较

    #[test]
    fn create() {
        // 创建一个HashMap，用于存储宝石种类和对应的数量
        let mut my_gems = HashMap::new();
        my_gems.insert("new", 1);

        let capacity = 12; //预先设置大小
        let mut new_map = HashMap::with_capacity(capacity);
        new_map.insert("capacity", capacity);

        println!("{:?}", my_gems);
        println!("{:?}", new_map);
        //元组
        let teams_list = vec![
            ("中国队".to_string(), 100),
            ("美国队".to_string(), 10),
            ("日本队".to_string(), 50),
        ];

        /*
                let mut teams_map = HashMap::new();
                for team in &teams_list {
                    teams_map.insert(&team.0, team.1);
                }
        */
        // into_iter 方法将列表转为迭代器，接着通过 collect 进行收集
        // collect 方法在内部实际上支持生成多种类型的目标集合，需要通过类型标注 HashMap<_,_> 让编译器自行推倒
        let teams_map: HashMap<_, _> = teams_list.into_iter().collect();
        println!("{:?}", teams_map)
    }

    #[test]
    fn owner() {
        /*    HashMap 的所有权规则与其它 Rust 类型没有区别：
        若类型实现 Copy 特征，该类型会被复制进 HashMap，因此无所谓所有权
             若没实现 Copy 特征，所有权将被转移给 HashMap 中 */

        let name = String::from("Sunface");
        let age = 18;

        let mut handsome_boys = HashMap::new();

        //=====
        //  handsome_boys.insert(&name, age); //name借用发生在此处
        //  std::mem::drop(name); // name的所有权被转移走
        //  println!("{:?}", handsome_boys); //所有权转移后，还试图使用name
        //=====

        // name` has type `String`, which does not implement the `Copy` trait
        handsome_boys.insert(name, age); // move
        // println!("{}", name);
        println!("{}", age);
    }

    #[test]
    fn method() {
        let mut scores = HashMap::new();

        scores.insert(String::from("Blue"), 10);
        scores.insert(String::from("Yellow"), 50);

        let team_name = String::from("Blue");
        println!("{:?}", scores.get(&team_name));
        println!("{:?}", scores.get(&team_name).copied().unwrap_or(0));

        for (key, value) in &scores {
            println!("for :{}: {}", key, value);
        }
    }

    #[test]
    fn method_() {
        let mut scores = HashMap::new();
        scores.insert("Blue", 10);

        // 覆盖已有的值
        let old = scores.insert("Blue", 20);
        assert_eq!(old, Some(10));

        // 查询新插入的值
        let new = scores.get("Blue");
        assert_eq!(new, Some(&20));

        // 查询Yellow对应的值，若不存在则插入新值
        let v = scores.entry("Yellow").or_insert(5);
        assert_eq!(*v, 5); // 不存在，插入5

        // or_insert 返回了 &mut v 引用，因此可以通过该可变引用直接修改 map 中对应的值

        let v = scores.entry("Yellow").or_insert(50);
        assert_eq!(*v, 5); // 已经存在，因此50没有插入
    }
}
